home *** CD-ROM | disk | FTP | other *** search
/ Hardcore Visual Basic 5.0 (2nd Edition) / Hardcore Visual Basic 5.0 - Second Edition (1997)(Microsoft Press).iso / Code / random.cls < prev    next >
Text File  |  1997-06-14  |  5KB  |  145 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4. END
  5. Attribute VB_Name = "GRandom"
  6. Attribute VB_GlobalNameSpace = True
  7. Attribute VB_Creatable = True
  8. Attribute VB_PredeclaredId = False
  9. Attribute VB_Exposed = True
  10. Option Explicit
  11.  
  12. Public Enum EErrorRandom
  13.     eeBaseRandom = 13580    ' Random
  14. End Enum
  15.  
  16. ' For Random algorithm
  17. Private iLast As Long
  18. Private Const A As Long = 48271
  19. Private Const M As Long = 2147483647
  20. Private Const Q As Long = (M / A)
  21. Private Const R As Long = (M Mod A)
  22. Private Const rT As Single = 1# / M
  23.  
  24. Private Sub Class_Initialize()
  25.     iLast = Abs(timeGetTime)
  26. End Sub
  27.  
  28. ' Pedigree for the Random and Seed algorithms
  29.  
  30. '****************************************************************************
  31. '* PMMMLCG - Prime Modulus M Multiplicative Linear Congruential Generator   *
  32. '*  Modified version of the random number generator proposed by             *
  33. '*  Park & Miller in "Random Number Generators: Good Ones Are Hard to Find" *
  34. '*  CACM October 1988, Vol 31, No. 10                                       *
  35. '*   - Modifications proposed by Park to provide better statistical         *
  36. '*     properties (i.e. more "random" - less correlation between sets of    *
  37. '*     generated numbers                                                    *
  38. '*   - generator is of the form                                             *
  39. '*         x = ( x * A) % M                                                 *
  40. '*   - Choice of A & M can radically modify the properties of the generator *
  41. '*     the current values were chosen after followup work to the original   *
  42. '*     paper mentioned above.                                               *
  43. '*   - The generator has a period of 2^31 - 1 with numbers generated in the *
  44. '*     range of 0 < x < M                                                   *
  45. '*   - The generator can run on any machine with a 32-bit integer, without  *
  46. '*     overflow.                                                            *
  47. '*   - This generator is currently running on Sun 3/50, Sparc, IBM PC/XT,   *
  48. '*     IBM RS/6000 just to name a few...                                    *
  49. '****************************************************************************
  50. '*    John Burton                                                           *
  51. '*    G & A Technical Software, Inc                                         *
  52. '*    28 Research Drive                                                     *
  53. '*    Hampton, Va. 23666                                                    *
  54. '*                                                                          *
  55. '*    jcburt@cs.wm.edu                                                      *
  56. '*    jcburt@gatsibm.larc.nasa.gov                                          *
  57. '*    burton@asdsun.larc.nasa.gov                                           *
  58. '****************************************************************************
  59.  
  60. '*  Random() - return next random number
  61. '*
  62. '*      The Random() subroutine returns a pseudo-random long value in
  63. '*      the range Min <= x < Max
  64. Function Random(Optional ByVal iMin As Long = 0, _
  65.                 Optional ByVal iMax As Long = M) As Long
  66.     Dim iLo As Long, iHi As Long, iT As Long
  67. #If fComponent = 0 Then
  68.     If iLast = 0 Then Class_Initialize
  69. #End If
  70.     iHi = iLast / Q
  71.     iLo = iLast Mod Q
  72.   
  73.     iT = A * iLo - R * iHi
  74.     If iT > 0 Then
  75.         iLast = iT
  76.     Else
  77.         iLast = iT + M
  78.     End If
  79.     Random = iLast
  80.     If iMin <> 0 Or iMax <> M Then
  81.         If iMin < iMax Then
  82.             Random = iMin + (iLast Mod (iMax - iMin + 1))
  83.         Else
  84.             Random = iMax + (iLast Mod (iMin - iMax + 1))
  85.         End If
  86.     End If
  87.  
  88. End Function
  89.  
  90. '*  RandomReal() - return next random number
  91. '*
  92. '*      The RandomReal() function returns a pseudo-random floating point value
  93. '*      in the range 0.0 <= x < 1.0.
  94. Function RandomReal() As Single
  95.     RandomReal = CSng(Random * rT)
  96. End Function
  97.  
  98. '*  Seed - Set first random number in a sequence based on a seed
  99. '*
  100. '*      The Seed procedure sets the starting point for generating a series
  101. '*      of pseudo-random values. To re-initialize the generator with the same
  102. '*      sequennce, use -1 as the seed argument. Use any positive seed value sets the generator to a random
  103. '*      starting point.
  104. '*
  105. '*      Calling Random or RandomReal before any call to Seed will generate a
  106. '*      sequence based on the system timer.
  107.  
  108. Sub Seed(Optional ByVal iSeed As Long = -1)
  109.  
  110.     Static iLastSeed As Long
  111.     Select Case iSeed
  112.     Case -1
  113.         ' -1 reserved for reinitializing last sequence
  114.         If iLastSeed Then iLast = iLastSeed Else iLast = Abs(timeGetTime)
  115.     Case 0
  116.         ' Algorithm won't handle 0 seed, so use it to represent timer
  117.         iLast = Abs(timeGetTime)
  118.     Case Else
  119.         iLast = Abs(iSeed)
  120.     End Select
  121.     iLastSeed = iLast
  122.     
  123. End Sub
  124.  
  125. #If fComponent = 0 Then
  126. Private Sub ErrRaise(e As Long)
  127.     Dim sText As String, sSource As String
  128.     If e > 1000 Then
  129.         sSource = App.ExeName & ".Random"
  130.         Select Case e
  131.         Case eeBaseRandom
  132.             BugAssert True
  133.        ' Case ee...
  134.        '     Add additional errors
  135.         End Select
  136.         Err.Raise COMError(e), sSource, sText
  137.     Else
  138.         ' Raise standard Visual Basic error
  139.         sSource = App.ExeName & ".VBError"
  140.         Err.Raise e, sSource
  141.     End If
  142. End Sub
  143. #End If
  144.  
  145.